/**
 * Java Enterprise in a Nutshell, Third Edition, 
 * by Jim Farley and William Crawford 
 * with Prakash Malani, John G. Norman, and Justin Gehtland. 
 * Copyright 2006 O'Reilly Media, Inc., 0-596-10142-2.
 *
 * Modified by Vladimir Tarasov, 2009-08-26.
 * Tested with JDK 1.6.
 * The package folder containing the class file should be on the CLASSPATH.
 */
package tavl_rmi.account;

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

/**
 * AccountImpl: Implementation of the Account remote interface.
 * This class is used in both simple and factory RMI examples.
 */
public class AccountImpl extends UnicastRemoteObject implements Account {

    /**
     * Our current balance
     */
    private float mBalance = 0;
    /**
     * Name on account
     */
    private String mName = "";

    /**
     * Create a new account with the given name
     */
    public AccountImpl(String name) throws RemoteException {
        mName = name;
    }

    public String getName() throws RemoteException {
        return mName;
    }

    public float getBalance() throws RemoteException {
        return mBalance;
    }

    /**
     * Withdraw some funds
     */
    public void withdraw(float amt)
            throws RemoteException, InsufficientFundsException {
        if (mBalance >= amt) {
            mBalance -= amt;
            // Log transaction...
            System.out.println("--> Withdrew " + amt +
                    " from account " + getName());
            System.out.println("    New balance: " + getBalance());
        } else {
            throw new InsufficientFundsException("Withdrawal request of " +
                    amt + " exceeds balance of " + mBalance);
        }
    }

    /**
     * Deposit some funds
     */
    public void deposit(float amt) throws RemoteException {
        mBalance += amt;
        // Log transaction...
        System.out.println("--> Deposited " + amt +
                " into account " + getName());
        System.out.println("    New balance: " + getBalance());
    }

    /**
     * Move some funds from another (remote) account into this one
     */
    public void transfer(float amt, Account src)
            throws RemoteException, InsufficientFundsException {
        if (checkTransfer(src, amt)) {
            src.withdraw(amt);
            this.deposit(amt);
            // Log transaction...
            System.out.println("--> Transferred " + amt +
                    " from account " + src.getName());
            System.out.println("    New balance: " + getBalance());
        } else {
            throw new InsufficientFundsException("Source account balance " +
                    "is insufficient for transfer");
        }
    }

    /**
     * Check to see if the transfer is possible, given the source account
     */
    private boolean checkTransfer(Account src, float amt) {
        boolean approved = false;
        try {
            if (src.getBalance() >= amt) {
                approved = true;
            }
        } catch (RemoteException re) {
            // If some remote exception occurred, then the transfer is still
            // compromised, so return false
            approved = false;
        }
        return approved;
    }
}